package cn.itcast.zt.java8.doubleColor;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.util.StrUtil;
import org.junit.Before;
import org.junit.Test;

import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 双色球随机数
 * create by zhangtian105 on 2022/5/21
 */
public class DoubleColorBallDemo {
    private Integer[] redBall = new Integer[33] ;
    private Integer[] blueBall = new Integer[16] ;
    List<HisDoubleColor> hisDoubleColors = new ArrayList<>() ;
    NowDoubleColor nowDoubleColor = null ;

    /**
     * 初始化双色球球号
     */
    @Before
    public void initDoubleBall() {
        // 穷举所有号码入数组
        for (int i = 0; i < 33; i++) {
            redBall[i] = i + 1 ;
        }

        for (int j = 0; j < 16; j++) {
            blueBall[j] = j + 1 ;
        }

        hisDoubleColors = getHistoryDoubleColorData() ;
        // 历史数据重复数字排查
        // getHistoryRepeatPercent();
        nowDoubleColor = getNowDoubleColorData() ;
    }

    /**
     * 生成双色球号码
     */
    @Test
    public void getDoubleColorBall() {
        System.out.println("---------------- 打印结果 -----------------");

        System.out.println("---------- 四组数字与历史相同 ----------");
        while(!checkPercent(nowDoubleColor, 4, 2)) {
            nowDoubleColor = getNowDoubleColorData() ;
        }

        printResult(nowDoubleColor);

        System.out.println("---------- 三组数字与历史相同 ----------");
        // 3组数字与历史相同
        while(!checkPercent(nowDoubleColor, 3, 61)) {
            nowDoubleColor = getNowDoubleColorData() ;
        }

        printResult(nowDoubleColor);

        System.out.println("---------- 两组组数字与历史相同 ----------");
        // 2组数字与历史相同
        while(!checkPercent(nowDoubleColor, 2, 500)) {
            nowDoubleColor = getNowDoubleColorData() ;
        }

        printResult(nowDoubleColor);

        System.out.println("---------- 完全随机 ----------");
        nowDoubleColor = getNowDoubleColorData() ;

        printResult(nowDoubleColor);
    }

    private boolean checkPercent(NowDoubleColor nowDoubleColor, int repeatNum, int needNum) {
        // 篮球规律方法
        Integer[] nowBlueColor = nowDoubleColor.getNowBlueBall() ;

        // 递减法获取重复球数字的概率
        // 红球重复法
        Integer[] nowRedColor = nowDoubleColor.getNowRedBall() ;
        Integer repeatCountNum = 0 ;
        for (int j = 0; j < hisDoubleColors.size(); j++) {
            if (j == 0) {
                Integer[] hisBlueColor = hisDoubleColors.get(0).getHisBlueBall() ;
               /* if (hisBlueColor[0] % 2 == 0 && nowBlueColor[0] % 2 != 0) {
                    return false ;
                }*/

                if (hisBlueColor[0] % 2 != 0 && !(nowBlueColor[0] % 2 == 0)) {
                    return false ;
                }
            }

            Integer[] nextHisRedColor = hisDoubleColors.get(j).getHisRedBall() ;

            Integer count = 0 ;
            for (int k = 0; k < 6; k++) {
                Integer a = nowRedColor[k] ;
                for (int m = 0; m < 6; m++) {
                    Integer b = nextHisRedColor[m] ;

                    if (a.equals(b)) {
                        count ++ ;
                    }
                }

                if (count >= repeatNum) {
                    repeatCountNum ++ ;
                }
            }
        }

        // System.out.println("打印获取的重复数据的概率:" +repeatCountNum);

        if (repeatCountNum > needNum) {
            return true ;
        }else {
            return false ;
        }
    }

    private void getHistoryRepeatPercent() {
        // 递减法获取重复球数字的概率
        for (int i = 0; i < hisDoubleColors.size(); i++) {
            // 红球重复法
            Integer[] hisRedColor = hisDoubleColors.get(i).getHisRedBall() ;
            Integer repeatCountNum = 0 ;
            for (int j = i + 1; j < hisDoubleColors.size(); j++) {
                Integer[] nextHisRedColor = hisDoubleColors.get(j).getHisRedBall() ;

                Integer count = 0 ;
                for (int k = 0; k < 6; k++) {
                    Integer a = hisRedColor[k] ;
                    for (int m = 0; m < 6; m++) {
                        Integer b = nextHisRedColor[m] ;

                        if (a.equals(b)) {
                            count ++ ;
                        }
                    }

                    if (count >= 3) {
                        repeatCountNum ++ ;
                    }
                }
            }

            System.out.println("打印获取的重复数据的概率:" +repeatCountNum);
        }
    }

    public void printResult(NowDoubleColor nowDoubleColor) {
        // 生成红球数据
        String redBalls = "" ;
        for (Integer finalRedBall : nowDoubleColor.getNowRedBall()) {
            redBalls = redBalls + " " + finalRedBall ;
        }

        // 生成篮球数据
        String blueBalls = "" ;
        for (Integer finalBlueBall : nowDoubleColor.getNowBlueBall()) {
            blueBalls = finalBlueBall + "" ;
        }

        System.out.println("双色球中奖号码:【红球】" + redBalls + "【篮球】" + blueBalls);
    }

    public NowDoubleColor getNowDoubleColorData() {
        // 随机取出来一个蓝色的球+6个不重复的红色的球
        Set<Integer> finalRedBalls = new TreeSet<>() ;
        Set<Integer> finalBlueBalls = new HashSet<>() ;

        // 设置一个篮球
        ThreadLocalRandom blueRandom = ThreadLocalRandom.current() ;
        Integer blueRange = blueRandom.nextInt(1, 5) ;
        while(finalBlueBalls.size() < 1) {
            Integer blueNum = 0 ;
            if (blueRange == 1) {
                blueNum = blueRandom.nextInt(0, 4) ;
            }else if (blueRange == 2) {
                blueNum = blueRandom.nextInt(4, 8) ;
            }else if (blueRange == 3) {
                blueNum = blueRandom.nextInt(8, 12) ;
            }else {
                blueNum = blueRandom.nextInt(12, 16) ;
            }
            finalBlueBalls.add(blueBall[blueNum]) ;
        }

        // 设置6个红球
        ThreadLocalRandom redRandom = ThreadLocalRandom.current() ;
        while(finalRedBalls.size() < 6) {
            Integer redRange = redRandom.nextInt(1, 5) ;
            Integer redNum = 0 ;
            if (redRange == 1) {
                redNum = blueRandom.nextInt(0, 8) ;
            }else if (redRange == 2) {
                redNum = blueRandom.nextInt(8, 16) ;
            }else if (redRange == 3) {
                redNum = blueRandom.nextInt(16, 24) ;
            }else {
                redNum = blueRandom.nextInt(24, 33) ;
            }

            finalRedBalls.add(redBall[redNum]) ;
        }

        NowDoubleColor nowDoubleColor = new NowDoubleColor() ;
        Integer[] nowRedBall = new Integer[6] ;
        Integer[] nowBlueBall = new Integer[1] ;

        int i = 0 ;
        for (Integer finalRedBall : finalRedBalls) {
            nowRedBall[i] = finalRedBall ;
            i++ ;
        }

        int j = 0 ;
        for (Integer finalBlueBall : finalBlueBalls) {
            nowBlueBall[j] = finalBlueBall ;
            j++ ;
        }

        nowDoubleColor.setNowRedBall(nowRedBall);
        nowDoubleColor.setNowBlueBall(nowBlueBall);

        return nowDoubleColor ;
    }

    private List<HisDoubleColor> getHistoryDoubleColorData() {
        String path = FileUtil.getAbsolutePath("historyRecord.txt") ;
        FileReader fileReader = new FileReader(path) ;
        List<String> resultList = fileReader.readLines() ;

        List<HisDoubleColor> hisDoubleColors = new ArrayList<>(resultList.size()) ;
        for (String result : resultList) {
            HisDoubleColor hisDoubleColor = new HisDoubleColor() ;
            List<String> hisStrList = StrUtil.splitTrim(result, ",") ;
            Integer[] hisRedBall = new Integer[6] ;
            Integer[] hisBlueBall = new Integer[1] ;
            for (int i = 0; i < hisStrList.size(); i++) {
                if (i <= 5) {
                    hisRedBall[i] = Integer.valueOf(hisStrList.get(i)) ;
                }else {
                    hisBlueBall[0] = Integer.valueOf(hisStrList.get(i)) ;
                }
            }

            hisDoubleColor.setHisRedBall(hisRedBall);
            hisDoubleColor.setHisBlueBall(hisBlueBall);

            hisDoubleColors.add(hisDoubleColor) ;
        }

        return hisDoubleColors ;
    }
}
